using System;
using System.IO;
using System.Reflection;
using System.Threading;
using AutoTest.Core.Utils;
using log4net;

namespace AutoTest.Core.Infrastructure.Files
{
    public class FileSystem : IFileSystem
    {
        private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        public string ReadAllText(string filename)
        {
            if (filename.IsNullOrEmptyTrimmed())
                return "";

            if (!File.Exists(filename))
                return "";

            return RetryThreeTimesIfLocked(() => File.ReadAllText(filename));
        }

        public string FindFileInDirectoryTree(string filename, string rootFolderToSearch)
        {
            var foundFilenames = Directory.GetFiles(rootFolderToSearch, filename, SearchOption.AllDirectories);
            if (foundFilenames.Length == 0)
                return "";
            return foundFilenames[0];
        }

        private string RetryThreeTimesIfLocked(Func<string> readAllText)
        {
            var text = "";
            var attempt = 0;
            var success = false;
            while (!success && attempt < 3)
            {
                try
                {
                    attempt++;
                    text = readAllText();
                    success = true;
                }
                catch (IOException)
                {
                    Logger.DebugFormat("File is locked for reading, retrying {0}...", attempt);
                    Thread.Sleep(100);
                }
            }
            if (attempt >= 3)
                throw new ApplicationException("Unable to read file.");

            return text;
        }
    }
}